package com.xiyuan.smartutils.template.engine.expression.operator.comparison;

import com.xiyuan.smartutils.Types;

import com.xiyuan.smartutils.template.engine.VariableMap;
import com.xiyuan.smartutils.template.engine.expression.Expression;
import com.xiyuan.smartutils.template.engine.expression.operator.Operator;

/**
 * 不等比较(!=)
 * 
 * @author lgz 2020年12月7日 新建与整理
 */
public class _NE extends Operator
{
    private static final long serialVersionUID = 1L;
    private Expression left;
    private Expression right;
    
    public _NE(String path, int line, int column, Expression left, Expression right)
    {
        super(path, line, column);
        this.left = left;
        this.right = right;
        this.assertSymbo("不等于", left, right);
    }
    
    @Override
    public int getType()
    {
        return NOT_EQUAL;
    }
    
    @Override
    protected Object build(VariableMap variableMap)
    {
        Object prev = left.execute(variableMap);
        Object next = right.execute(variableMap);
        
        if (prev == null || next == null)
            return prev != next;
        
        if (prev instanceof String || next instanceof String)// 出现一个为字符串
            return String.valueOf(prev).equals(String.valueOf(next));
        
        if (Types.isInteger(prev))
        {
            if (Types.isInteger(next))
                return ((Number) prev).longValue() != ((Number) next).longValue();
            else if (Types.isDecimal(next))
                return ((Number) prev).longValue() != ((Number) next).doubleValue();
            else if (Types.isChar(next))
                return ((Number) prev).longValue() != ((Character) next).charValue();
        }
        else if (Types.isDecimal(prev))
        {
            if (Types.isInteger(next))
                return ((Number) prev).doubleValue() != ((Number) next).longValue();
            else if (Types.isDecimal(next))
                return ((Number) prev).doubleValue() != ((Number) next).doubleValue();
            else if (Types.isChar(next))
                return ((Number) prev).doubleValue() != ((Character) next).charValue();
        }
        else if (Types.isChar(prev))
        {
            if (Types.isInteger(next))
                return ((Character) prev).charValue() != ((Number) next).longValue();
            else if (Types.isDecimal(next))
                return ((Character) prev).charValue() != ((Number) next).doubleValue();
            else if (Types.isChar(next))
                return ((Character) prev).charValue() != ((Character) next).charValue();
        }
        
        // 最后
        return !prev.equals(next);
    }
    
    @Override
    public String toString()
    {
        return new StringBuilder().append(left).append(" != ").append(right).toString();
    }
}
